Introducción a R

Crear código en R, uso colaborativo y reproducible

Bienvenidxs!!

¿Quiénes somos?

Organización del curso

Por día

Lunes = introducción a R, crear código, buenas prácticas
Martes = manejo y visualizacion de datos
Miércoles = modelos lineales y factoriales
Jueves = modelos generalizados y multivariantes
Viernes = uso colaborativo, dudas, ejemplos

Por hora

  • 9 a 10 teoría
  • 10 a 10:45 ejercicios
  • 10:45 a 11 break
  • 11 a 12 teoría
  • 12 a 13 ejercicios y dudas

Hoy

  • Introducción, código básico
  • Ejercicios I
  • Funciones, bucles, dataframes
  • Ejercicios II y III

Lo que vas a aprender:

  • Mejorar la comprensión y la práctica estadística.

  • Desarrollar habilidades en programación en R.

  • Aprender flujos de trabajo eficientes, limpios y reproducibles.

  • Saber buscar información

  • No enredarse en errores

Lo que no vas a aprender

  • A programar en plan pro sin mirar internet o chatgpt

  • A hacer páginas web

  • A dejar de pelearte con la estadística

Objetivos de la clase

WordCloud

Introducción

R es un lenguaje y entorno de programación especializado en:

Análisis estadístico, visualización de datos y ciencia de datos.

Utilizado por investigadores, analistas y científicos para explorar, modelar y comunicar información basada en datos de forma eficiente y reproducible.

Muy utilizado en biología

Biólogxs en general

R y Rtudio

R → Es el lenguaje de programación y el motor que realiza los cálculos estadísticos y el análisis de datos.

RStudio → Es un entorno de desarrollo integrado (un programa) que facilita el uso de R con una interfaz amigable, paneles, autocompletado y herramientas visuales.

Ejemplo mesa de trabajo

¿Qué puede hacer R?

  • Calcular y analizar (operaciones matemáticas, modelos, simulaciones, tests…)
  • Trabajar con datos (leer y escribir tablas, limpiar datos, transformar datos)
  • Visualizar (graficos estadísticos, interactivos, mapas, animaciones, etc)
  • Automatizar y extender (crear funciones propias, desarrollar paquetes, reproducir analisis facilmente)
  • Comunicar (crear informes Quarto o RMarkdown, crear webs o apps Shiny) Ejemplo quarto ## Workflow: lo básico básico

Es una calculadora: se pueden hacer operaciones básicas multiplicar, dividir, sumar, restar…

2 + 3     
[1] 5
10 - 4    
[1] 6
3 * 5     
[1] 15
20 / 4    
[1] 5

Operaciones básicas de lógica

Las operaciones lógicas comparan valores y devuelven un resultado lógico.

TRUE se comporta como 1 y FALSE como 0. Se pueden sumar o usar en cálculos.

20 / 4 >= 10    # ¿5 es mayor o igual que 10? → FALSE
[1] FALSE
20 / 4 == 10    # ¿5 es igual a 10? → FALSE
[1] FALSE
20 / 4 < 10     # ¿5 es menor que 10? → TRUE
[1] TRUE
valores <- c(TRUE, FALSE, TRUE, TRUE)
sum(valores)       # cuenta cuántos TRUE hay
[1] 3
mean(valores)      # proporción de TRUE
[1] 0.75

Cuidado que en R “=” y “<-” son sinónimos!

Acumular información

La magia de los objetos

x <- 10    
y <- 5
suma <- x + y
suma
[1] 15
suma + 7
[1] 22

Espera, pero ¿qué son los objetos?

Los objetos empiezan por una letra

Son sensibles a mayusculas

Tienen que llevar nombres coherentes y un orden

yo_uso_la_serpiente <- 10
OtraGenteUsaElCamello <- 9
otra.gente.usa.los.puntos <- 9
Hayque_evitar.esto10 <- 2

Tipos de objetos

Hay muuchos tipos de objetos

  • numéricos, caracteres, matrices, tablas, listas
  • modelos, polígonos, funciones
numero <- 1:10
numero
 [1]  1  2  3  4  5  6  7  8  9 10
caracter <- "del uno al diez"
caracter
[1] "del uno al diez"
una_lista <- list(1:10, 11:20, 21:30)
una_lista
[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10

[[2]]
 [1] 11 12 13 14 15 16 17 18 19 20

[[3]]
 [1] 21 22 23 24 25 26 27 28 29 30

Podemos transformar objetos de un tipo en otro con as.xxxx()

numeros_como_caracteres <- as.character(numero)
numeros_como_caracteres
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"
numeros <- as.numeric(numeros_como_caracteres)
numeros
 [1]  1  2  3  4  5  6  7  8  9 10

Vectores y operaciones con vectores

Creamos vectores, que son elementos del mismo tipo juntos (numérico, carácter). Es un poco como una fila de una tabla… se pueden crear con 1:10 (numeros del 1 al 10)

Consecutivos del 1:10

Combinando c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Generador de secuencias: del 0 al 100 cada 10 seq(0, 100, 10)

numeros <- c(1, 2, 3, 4, 5) 
numeros
[1] 1 2 3 4 5
otros_numeros <- 1:40
otros_numeros
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
otros_numeros + 10
 [1] 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
[26] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
promedio <- mean(numeros)
promedio
[1] 3
promedio * numeros
[1]  3  6  9 12 15
numeros / otros_numeros
 [1] 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 0.16666667
 [7] 0.28571429 0.37500000 0.44444444 0.50000000 0.09090909 0.16666667
[13] 0.23076923 0.28571429 0.33333333 0.06250000 0.11764706 0.16666667
[19] 0.21052632 0.25000000 0.04761905 0.09090909 0.13043478 0.16666667
[25] 0.20000000 0.03846154 0.07407407 0.10714286 0.13793103 0.16666667
[31] 0.03225806 0.06250000 0.09090909 0.11764706 0.14285714 0.02777778
[37] 0.05405405 0.07894737 0.10256410 0.12500000
# [ ] para seleccionar partes de un vector o una tabla
(numeros / otros_numeros)[8]
[1] 0.375

Generadores de distribuciones

R es muy potente generando distribuciones.
Una distribución describe cómo se reparten los valores de una variable.

Números al azar → todos con la misma probabilidad UNIFORME ### Ejemplo Distribución uniforme

# Un vector de 5 números aleatorios con distribución uniforme
runif(5)
[1] 0.90211519 0.06880823 0.19890502 0.83205602 0.72943058
# Ahora que 3 números vayan del 0 al 100
runif(3, min=0, max=100)
[1] 70.32476 86.77784 26.50731
# Cómo se ve
x <- runif(1000, min = 0, max = 100)
hist(x, col = "orange", main = "Distribución uniforme", xlab = "Número de eventos", ylab = "Frecuencia")

Distribución normal

Alturas de personas → muchas alrededor del promedio (forma de campana) NORMAL

# 4 números con una distribución normal
rnorm(4)
[1]  1.46836807 -0.53007266 -0.01239084  0.01500239
# Especificando la media y la desviación
x <- rnorm(1000, mean = 50, sd = 10)
hist(x, col = "skyblue", main = "Distribución normal", xlab = "Número de eventos", ylab = "Frecuencia")

Distribución poisson

Conteo POISSON

# Generar 1000 observaciones con media (λ) = 3
x <- rpois(1000, lambda = 3)

# Ver las primeras observaciones
head(x)
[1] 4 5 3 0 2 1
# Histograma
hist(x, col = "lightgreen", main = "Distribución de Poisson (λ = 3)", xlab = "Número de eventos", ylab = "Frecuencia")

Distribución binomial negativa

Resultados de “éxito o fracaso” (como lanzar una moneda) BINOMIAL

# Binomial
# 20 experimentos, en cada uno lanzamos una monedas, con una probabilidad de que salga cara del 50%
caras <- rbinom(200, size = 1, prob = 0.5)
table(caras)
caras
  0   1 
103  97 
barplot(table(caras), col = "steelblue")

Funciones básicas y útiles

Las funciones son aplicaciones que nos permiten realizar operaciones muy diversas.

  • Funciones que vienen con la distribución base de R o en los paquetesya creados por los usuarios
# c () concatenar
x <- c(4, 6, 8, 3, 9, 12, 12)

# Estadísticos básicos
mean(x)       # media
[1] 7.714286
median(x)     # mediana
[1] 8
sd(x)         # desviación estándar
[1] 3.59232
min(x)        # valor mínimo
[1] 3
max(x)        # valor máximo
[1] 12
range(x)      # rango (min, max)
[1]  3 12
summary(x)    # resumen general
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  3.000   5.000   8.000   7.714  10.500  12.000 

Ayuda

Ayuda para funciones en R (o también vale buscar en google “function mean in R”)

# Ayudas
?mean           # abre la ayuda de una función
help(mean)      # lo mismo que '?mean'
??"normal"      # búsqueda más amplia en toda la documentación

Mas funciones básicas y útiles

Aleatoriedad

x <- rpois(8, 8)
x
[1] 12 12  4  7  5  6  8  8
sample(x, 3)          # elegir 3 elementos al azar
[1] 12  8  6
rev(x)                # invertir el orden
[1]  8  8  6  5  7  4 12 12
sort(x)               # ordenar valores
[1]  4  5  6  7  8  8 12 12

Conteos y valores únicos

length(x)             # longitud del vector
[1] 8
table(x)              # tabla de frecuencias
x
 4  5  6  7  8 12 
 1  1  1  1  2  2 
unique(x)             # valores únicos
[1] 12  4  7  5  6  8
length(unique(x))     # cuántos valores distintos
[1] 6
sample(x, 3, replace=TRUE) 
[1] 8 4 8
round(mean(x), 2)     # redondear a 2 decimales
[1] 7.75

Nombres y texto

nombres <- c("Laura", "Rocio", "Violeta", "Rocio", "Rocio")
unique (nombres)
[1] "Laura"   "Rocio"   "Violeta"
table (nombres)
nombres
  Laura   Rocio Violeta 
      1       3       1 
rep (nombres, 5)    # repetir algo varias veces
 [1] "Laura"   "Rocio"   "Violeta" "Rocio"   "Rocio"   "Laura"   "Rocio"  
 [8] "Violeta" "Rocio"   "Rocio"   "Laura"   "Rocio"   "Violeta" "Rocio"  
[15] "Rocio"   "Laura"   "Rocio"   "Violeta" "Rocio"   "Rocio"   "Laura"  
[22] "Rocio"   "Violeta" "Rocio"   "Rocio"  
sample(nombres, 3, replace=TRUE) 
[1] "Rocio" "Rocio" "Rocio"

Ejercicios I

# 1. Calcula el minimo valor de 100 valores aleatorios según una distribución normal
min (rnorm (100))
[1] -2.60032
# 2. Dada una secuencia de 20 números seguidos (del 0 al 20), genera los pares y guárdalo en un objeto.
pares <- seq (0, 20, 2)

# 3. Ejercicio:

  # Crea un vector con 20 números aleatorios entre 0 y 50.
  # Calcula el promedio y la desviación estándar.
  # Multiplica todos los valores por 2.
  # Dibuja un histograma.
  #¿Cómo cambia el promedio después de multiplicar por 2?

mi_vector <- runif(20,0,50)
mean (mi_vector)
[1] 26.21174
sd (mi_vector)
[1] 12.89635
mi_vector_2 <- mi_vector*2
hist(mi_vector_2)
# Crea un vector con edades y usa una comparación para saber cuáles son mayores de edad y cualcula cuantos no lo son
edades <- c(12, 18, 3, 44, 25, 15, 30)
sum (edades > 18)
[1] 3

Crear funciones

  • Crear nuestras propias funciones con function().
  • Asignarle un nombre
  • Indicar argumentos
  • Escribir entre llaves el código

Ejemplo de funciones

# Queremos la media de nuestros números transformados a logaritmo

vector <- seq(1, 100, 10)
mean (log (vector))
[1] 3.380067
sd (log (vector))
[1] 1.355705
# Queremos hacerlo otra vez con otros valores

vector2 <- seq(1, 300, 50)
mean (log (vector2))
[1] 4.065497
sd (log (vector2))
[1] 2.069674
log_vect <- function (y) {
  mean_y <- mean (log (y+1))
  sd_y <- sd (log (y+1))
  print(paste("La media es", mean_y, ", la desviación estándar es:", round(sd_y,2)))
  return(log(y))
}

vector3 <- seq(1, 300, 4)
distribution = log_vect (vector3)
[1] "La media es 4.70839604852934 , la desviación estándar es: 0.98"
hist(distribution)

Bucles - for ()

R repite algo automáticamente sin que lo escribas varias veces.

paste(“Aquí está el número”, 1) paste(“Aquí está el número”, 2) paste(“Aquí está el número”, 3) paste(“Aquí está el número”, 4) paste(“Aquí está el número”, 5)

# i puede ser un número
length(1:5) # número de iteraciones 
[1] 5
for (i in 1:5) {
  print(paste("Aquí está el número", i))
}
[1] "Aquí está el número 1"
[1] "Aquí está el número 2"
[1] "Aquí está el número 3"
[1] "Aquí está el número 4"
[1] "Aquí está el número 5"
# i puede ser un caracter 
nombres <- c ("Laura", "Rocio", "Violeta")
length(nombres) #número de iteraciones 
[1] 3
for (i in nombres) {
  print(paste("Aquí está la alumna", i))
}
[1] "Aquí está la alumna Laura"
[1] "Aquí está la alumna Rocio"
[1] "Aquí está la alumna Violeta"

Bucles II

Con un dado ahora

# un dado
sample(1:6, 1)
[1] 6
# i puede ser solo el numero de veces que repetimos algo
resultados <- c()
for (i in 1:100) {
  tiro <- sample(1:6, 1)
  resultados <- c(resultados, tiro)
}

resultados
  [1] 2 6 6 5 2 2 4 4 5 3 3 4 2 6 4 6 4 5 3 3 1 3 5 6 6 1 2 4 2 2 3 1 5 4 5 2 2
 [38] 5 4 6 6 2 4 6 1 5 4 4 3 6 6 5 6 3 6 3 4 4 2 4 3 1 2 2 4 4 3 6 1 3 5 6 3 1
 [75] 1 1 3 3 1 4 4 1 4 6 6 2 6 2 1 6 3 6 2 2 2 4 6 5 4 6
mean(resultados)
[1] 3.67
# 1. Ejercicio: como podemos saber cuantas veces ha salido el numero 2?
sum(resultados==2)
[1] 18

Volvemos a nuestro ejemplo

# Queremos repetir el cálculo de media y desviación logarítmica

# para varios vectores distintos

vectores <- list (seq(1, 100, 10), seq(1, 300, 50), seq(1, 500, 100))

# Creamos un bucle FOR

for (i in vectores) {
media <- mean(log(i + 1))
desv  <- sd(log(i + 1))
print(paste("Media:", round(media, 2), " | Desviación:", round(desv, 2)))
}
[1] "Media: 3.48  | Desviación: 1.16"
[1] "Media: 4.19  | Desviación: 1.8"
[1] "Media: 4.47  | Desviación: 2.17"
# Ahora queremos guardar los resultados

# Crear un vector vacío

resultados <- c()

for (i in vectores) {
media <- mean(log(i + 1))
desv  <- sd(log(i + 1))
filas <- data.frame(media=media, desv=desv)
resultados <- rbind(resultados, filas)
}

resultados
     media     desv
1 3.475605 1.164002
2 4.188490 1.800784
3 4.466653 2.171404

Apply, sapply, lapply

Otra forma de hacer bucles, pero en la misma linea

sapply(vectores, function(i) mean(log(i + 1)))
[1] 3.475605 4.188490 4.466653

ifelse

Condicionantes

if: R ejecuta el código dentro del bloque {} solo si la condición es verdadera.
if // else: si no se cumple la condición, haz esto otro
ifelse: lo mismo pero en una sola linea

x <- 10

if (x > 5) {
  print("El número es mayor que 5")
}
[1] "El número es mayor que 5"
x <- 3

if (x > 5) {
  print("El número es mayor que 5")
} else {
  print("El número es menor o igual que 5")
}
[1] "El número es menor o igual que 5"
edades <- c(15, 22, 35, 12)

ifelse(edades >= 18, "Adulto", "Menor")
[1] "Menor"  "Adulto" "Adulto" "Menor" 

Ejercicios 2

  1. Haz una función que diga si un número cualquiera es par o no

  2. Crea un vector con 10 temperaturas y usa ifelse() para clasificar cada valor como “Frío” o “Caluroso”

que_tipo_de_numero_soy <- function (x) {
ifelse(x %% 2 == 0, "par", "impar")
}

temperaturas <- rpois (10, 15)
clasificacion <- ifelse(temperaturas < 15, "frio", "caliente")
# Añade a una tabla esta clasificación ExtrA!
data.frame (temperaturas, clasificacion)
   temperaturas clasificacion
1            11          frio
2            13          frio
3            11          frio
4            19      caliente
5            15      caliente
6            16      caliente
7            19      caliente
8            20      caliente
9            20      caliente
10           28      caliente

Bases de datos

Una base de datos (data frame) es una tabla de datos, como una hoja de cálculo en excel, tiene filas (observaciones) y columnas (variables).

# Creamos vectores con información
nombres <-  c ("Laura", "Rocio", "Violeta")
edad <- c(23, 35, 29)
altura <- c(1.65, 1.80, 1.70)
profesion <- c("Bióloga", "Profesora", "Médica")

# Combinamos todo en un data frame
personas <- data.frame(
  NAME = nombres,
  AGE = edad,
  HEIGHT = altura,
  JOB = profesion)

personas[1,]
   NAME AGE HEIGHT     JOB
1 Laura  23   1.65 Bióloga
personas[,1]
[1] "Laura"   "Rocio"   "Violeta"
personas$NAME # Seleccionar columnas con $
[1] "Laura"   "Rocio"   "Violeta"
# head(personas)       
# str(personas)  
# summary(personas) 
# colnames(personas) 
# nrow(personas)  
# ncol(personas)
# View(personas) se abre en RStudio como una tabla interactiva.
# write_csv(personas, "data/personas.csv")

tabla vista en R (View)

Leer bases de datos

En la práctica, los datos vienen archivos externos:CSV, Excel, TXT, o bases de datos online. El formato .csv (comma separated values) es el más común. Cada columna está separada por una coma o punto y coma.

library(here)
# CSV
datos_csv <- read.csv(here("data/personas.csv"))
head(datos_csv)
     NAME AGE HEIGHT       JOB
1   Laura  23   1.65   Bióloga
2   Rocio  35   1.80 Profesora
3 Violeta  29   1.70    Médica
# EXCEL
library(readxl)
datos_excel <- read_excel(here("data/herbarium_df.xlsx")) #, sheet = 1 podríamos especificar el numero de hoja
head(datos_excel)
# A tibble: 6 × 19
     ID Collector        Collection_number Assistants  Family Taxon Author det  
  <dbl> <chr>            <chr>             <chr>       <chr>  <chr> <chr>  <chr>
1     1 Hermione Granger 2.0               Sprout, P.… SOLAN… Mand… L.     Spro…
2     2 Ron Weasley      5.0               Potter, H.  SALIC… Sali… Huff.  Spro…
3     3 Dobby H.E.       1.0               Winky H.E.  Zoste… Zost… (Huff… Long…
4     4 Pomona Sprout    1990-301a         Dumbledore… Suffo… Luci… Slyth. Spro…
5     5 Luna Lovegood    5.0               Xenophiliu… rosac… Prun… Rav.   Love…
6     6 Algie Longbottom 3.0               Longbottom… Mimbu… Mimb… Spore  Spro…
# ℹ 11 more variables: Det_date <chr>, life_form <chr>, Observations <chr>,
#   Height <chr>, Location <chr>, Area_description <chr>, Elevation <chr>,
#   Date <chr>, Latitude <chr>, Longitude <chr>, QR_code <chr>
# GOOGLE SHEETS
library(googlesheets4)
datos_gs <- read_sheet("https://docs.google.com/spreadsheets/d/1qC4lsXPpEcX1NmLdwiMJMC8X_WKX-EFQm4ahPdrNCZc/edit?usp=sharing")
head(datos_gs)
# A tibble: 4 × 5
  Nombre             Fecha               Titulo             Tipo.comm Afiliacion
  <chr>              <dttm>              <chr>              <chr>     <chr>     
1 Severus Snape      1993-01-01 00:00:00 Pociones avanzada… oral      Slytherin 
2 Minerva McGonagall 1994-01-01 00:00:00 De gato a humano:… poster    Gryffindor
3 Alastor Moody      1995-01-01 00:00:00 Distinguir entre … oral      Gryffindor
4 Rubeus Hagrid      1996-01-01 00:00:00 ¿Por qué no vuela… oral      Gryffindor
#write_csv(datos_gs, "data/datos_gs.csv")

Ejercicios 3

Base de datos de flores: Por cada sitio y pantrap, tenemos el numero de flores que tienen las especies de plantas en Doñana. Ejercicio: Importa la base de datos “flores.csv” de la carpeta “data”, explora la base de datos, calcula la abundancia media de flores total, indica cuantas especies distintas hay de plantas. Luego, crea una base de datos con el número de individuos por especie (no de flores). Guardala como csv.

flores <- read.csv(here("data/flores.csv"))
str(flores)
'data.frame':   490 obs. of  5 variables:
 $ code     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ site_id  : chr  "ANZ_1" "ANZ_1" "ANZ_1" "ANZ_1" ...
 $ pantrap  : int  1 1 1 2 2 2 2 3 3 4 ...
 $ species  : chr  "Oxalis pes-caprae" "Cistus salvifolius" "Ornithogalum umbellatum" "Cistus salvifolius" ...
 $ abundance: int  3 16 4 2 3 4 1 3 1 8 ...
mean(flores$abundance)
[1] 16.45102
length(unique(flores$species))
[1] 74
unique(flores$species)
 [1] "Oxalis pes-caprae"        "Cistus salvifolius"      
 [3] "Ornithogalum umbellatum"  "Aristolochia baetica"    
 [5] "Geranium rotundifolium"   "Aristolochia paucinervis"
 [7] "Reseda phyteuma"          "Ranunculus sp."          
 [9] "Anemone palmata"          "Cistus crispus"          
[11] "Cistus albidus"           "Erodium cicutarium"      
[13] "Lavandula stoechas"       "Ulex sp."                
[15] "Anagallis arvensis"       "Cistus ladanifer"        
[17] "na"                       "Rosmarinus officinalis"  
[19] "Crepis sp."               "Xolantha tuberaria"      
[21] "Lupinus angustifolius"    "Linaria spartea"         
[23] "Centaurea calcitrapa"     "Misopates orontium"      
[25] "Halimium calycinum"       "Echium sp."              
[27] "Senecio pequeño"          "Malcolmia lacera"        
[29] "Acis trichophylla"        "Leontodon sp."           
[31] "Raphanus raphanistrum"    "Erodium sp."             
[33] "Halimium halimifolium"    "Cerinthe major"          
[35] "Linum sp."                "Muscari"                 
[37] "Erodium"                  "Echium plantagineum"     
[39] "Vicia sp."                "Silene colorata"         
[41] "Sonchus oleraceus"        "Carduus bourgeanus"      
[43] "Senecio sp."              "Dipcadi serotium"        
[45] "Leontodon longirostris"   "Arum italicum"           
[47] "Centaurea sp."            "Genista hirsuta"         
[49] "Lysimachia arvensis"      "Carduus sp."             
[51] "Lathyrus ochrus"          "Muscari romoani"         
[53] "Daphne gnidium"           "Convolvulus althaeoides" 
[55] "Parentucellia viscosa"    "Cistus monspeliensis"    
[57] "Bituminaria bituminosa"   "Tolpis barbata"          
[59] "Campanula matritensis"    "Cistus libanotis"        
[61] "Stellaria media"          "Galactites tomentosa"    
[63] "Anthemis arvensis"        "Calycium"                
[65] "Andryala integrifolia"    "Gladius illyricus"       
[67] "Dipcadi sp."              "Chrysantenum sesetum"    
[69] "Serapias lingua"          "Leopoldia comosa"        
[71] "Cynoglossum creticum"     "Bellardia trixiajo"      
[73] "Xolantha guttata"         "Thapsia villosa"         
data.frame(table(flores$species))
                       Var1 Freq
1         Acis trichophylla    4
2        Anagallis arvensis    1
3     Andryala integrifolia   11
4           Anemone palmata   22
5         Anthemis arvensis    6
6      Aristolochia baetica   10
7  Aristolochia paucinervis    4
8             Arum italicum    1
9        Bellardia trixiajo    1
10   Bituminaria bituminosa    4
11                 Calycium    1
12    Campanula matritensis    1
13       Carduus bourgeanus    1
14              Carduus sp.    2
15     Centaurea calcitrapa    3
16            Centaurea sp.    1
17           Cerinthe major    1
18     Chrysantenum sesetum    3
19           Cistus albidus   11
20           Cistus crispus    8
21         Cistus ladanifer    2
22         Cistus libanotis    3
23     Cistus monspeliensis    2
24       Cistus salvifolius  114
25  Convolvulus althaeoides    8
26               Crepis sp.    5
27     Cynoglossum creticum    1
28           Daphne gnidium    1
29         Dipcadi serotium    2
30              Dipcadi sp.    1
31      Echium plantagineum    9
32               Echium sp.    4
33                  Erodium    1
34       Erodium cicutarium    4
35              Erodium sp.    9
36     Galactites tomentosa    9
37          Genista hirsuta    5
38   Geranium rotundifolium    2
39        Gladius illyricus    1
40       Halimium calycinum    9
41    Halimium halimifolium   12
42          Lathyrus ochrus    1
43       Lavandula stoechas   12
44   Leontodon longirostris    7
45            Leontodon sp.   23
46         Leopoldia comosa    1
47          Linaria spartea   10
48                Linum sp.    2
49    Lupinus angustifolius    2
50      Lysimachia arvensis    2
51         Malcolmia lacera   11
52       Misopates orontium    2
53                  Muscari    2
54          Muscari romoani    1
55                       na    1
56  Ornithogalum umbellatum    1
57        Oxalis pes-caprae    4
58    Parentucellia viscosa    1
59           Ranunculus sp.    2
60    Raphanus raphanistrum    1
61          Reseda phyteuma    7
62   Rosmarinus officinalis   10
63          Senecio pequeño    5
64              Senecio sp.    1
65          Serapias lingua    1
66          Silene colorata   20
67        Sonchus oleraceus    2
68          Stellaria media    1
69          Thapsia villosa    1
70           Tolpis barbata    3
71                 Ulex sp.    2
72                Vicia sp.    1
73         Xolantha guttata    6
74       Xolantha tuberaria   44
#write_csv (flores, "data/flores.csv")

Compartir código

  • git. Es una herramienta de control de versiones que además permite trabajar en equipo
  • GitHub (portfolio de programador) Perfil

Escribir textos, informes, artículos

  • Quarto
  • Rmarkdown
  • Ciencia reproducible y limpia

Bibliografía

cookbook :::::